 /** 
 * @addtogroup nmea
 * nmea
 * @brief NMEA分词器，负责NMEA报文分词处理
 * @par 示例
 * @code
    TNmeaTokenizer tok;
    // 完整(有效长度13)
    const char *ss = "$GPRMC,133306.00,A,3949.63075,N,11616.48616,E,0.513,,120116,,,A*7A";
    const char *se = ss + strlen(ss);
    
    int ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于13", 13 == ret);

    Assert(tc, "tokenizer[0] 不应该为空", !NmeaTokenIsEmpty(NmeaTokenizerGet(&tok, 0)));
    Assert(tc, "tokenizer[8] 应该为空", NmeaTokenIsEmpty(NmeaTokenizerGet(&tok, 8)));

    // 缺失校验码hh(有效长度13)
    ss = "$GPRMC,133306.00,A,3949.63075,N,11616.48616,E,0.513,,120116,,,A*";
    se = ss + strlen(ss);
    ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于13", 13 == ret);

    // 缺失*(有效长度13)
    ss = "$GPRMC,133306.00,A,3949.63075,N,11616.48616,E,0.513,,120116,,,A";
    se = ss + strlen(ss);
    ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于13", 13 == ret);

    // 空串
    se = ss;
    ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于0", ret == 0);

    // 开始位置大于结束位置
    ss++;
    ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于0", ret == 0);

    // 开始指针NULL
    ret = NmeaTokenizerInit(&tok, 0, se);
    Assert(tc, "tokenizer 结果应该等于0", ret == 0);

    // 结束指针NULL
    ret = NmeaTokenizerInit(&tok, ss, 0);
    Assert(tc, "tokenizer 结果应该等于0", ret == 0);

    // 指针NULL
    ret = NmeaTokenizerInit(&tok, 0, 0);
    Assert(tc, "tokenizer 结果应该等于0", ret == 0);

    ss = ",,,,,,,,,,,,9*";
    se = ss + strlen(ss);
    ret = NmeaTokenizerInit(&tok, ss, se);
    Assert(tc, "tokenizer 结果应该等于13", 13 == ret);
    
 * @endcode
 * @{
 */

/**
 * @file nmea_tokenizer.h
 * @brief NMEA分词器 
 * @details 负责NMEA报文分词处理
 * 
 * @author lzl(lzl@hopechart.com)
 * @date 2019-9-19
 * @version 1.1
 * @copyright 杭州鸿泉物联网技术股份有限公司
 * 
 * @par 修订日志
 * <table>
 * <tr><th>Date <th>Version <th> Author <th> Descripton
 * <tr><td>2019-9-19 <td>1.1 <td> liuzl <td> 建立初始版本
 * <tr><td>2020-11-21 <td>1.2 <td> akee <td> 新增NmeaTokenDecode接口
 * </table>
 * 
 */
#ifndef _HUBS_LIB_NMEA_TOKENIZER_H_
#define _HUBS_LIB_NMEA_TOKENIZER_H_

#include "nmea/nmea_types.h"
#include "nmea/nmea_token.h"

/**
 * 分词器结构
 */
struct NmeaTokenizerTag 
{
    int count;                                      ///< 个数
    TNmeaToken tokens[NMEA_TOKENS_MAX];             ///< token数组
};
typedef struct NmeaTokenizerTag TNmeaTokenizer;

#ifdef __cplusplus
extern "C" {
#endif

int NmeaTokenDecode(TNmeaTokenizer *t, const char *data, int data_size, int *remove_size);

/**
 * 初始化分词器
 *
 * @param t 分词器对象指针,不能为空
 * @param p 起始位置 
 * @param end 结束位置 
 *  
 * @return int 有效Token数量
 */
int NmeaTokenizerInit(TNmeaTokenizer *t, const char *p, const char *end);

/**
 * 取分词器指定索引字段
 * 
 * @param t 分词器对象指针,不能为空
 * @param index 索引号,范围[0~NMEA_TOKENS_MAX)
 * 
 * @return const TNmeaToken* 
 * @retval NULL 无效分词器或者索引超过实际数量
 * @retval 其他 索引对应的字段
 */
const TNmeaToken *NmeaTokenizerGet(TNmeaTokenizer *t, int index);

#ifdef __cplusplus
}
#endif
    
#endif//_HUBS_LIB_NMEA_TOKENIZER_H_

/**
 * @} 
 */














